package com.and9.mchen.mcmusic.dao.impl;

import java.sql.Timestamp;
import java.text.MessageFormat;
import java.util.List;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.and9.mchen.mcmusic.constant.RelationTable;
import com.and9.mchen.mcmusic.dao.IBaseEntityDao;
import com.and9.mchen.mcmusic.dao.IMusicStyleDao;
import com.and9.mchen.mcmusic.entity.MusicStyle;
import com.and9.mchen.mcmusic.entity.Singer;
import com.and9.mchen.mcmusic.entity.Song;
import com.and9.mchen.mcmusic.exception.DBException;
import com.and9.mchen.mcmusic.exception.DaoException;
import com.and9.mchen.mcmusic.util.EntityHelper;
import com.and9.mchen.mcmusic.util.GEntityHelper;
import com.and9.mchen.mcmusic.util.QueryHelper;

/**
 * 
 * @author MC
 * @version  1.0
 */
public class MusicStyleDaoImpl implements IMusicStyleDao{

	private final static Log log = LogFactory.getLog(MusicStyleDaoImpl.class);

	public static String TABLEMANE="music_style_table";
	
	public int createOrUpdateMusicStyle(MusicStyle musicStyle, 
			String... propertyNames) throws DaoException {
		
		if(GEntityHelper.isEmpty(musicStyle)){
			return -1;
		}
		
		String sqlStr=null;
		Object[] propertyValues=null;
		
		if(musicStyle.getId() == null || musicStyle.getId() <= 0){
			musicStyle.setCreateTime(new Timestamp(System.currentTimeMillis()));
			
			if(GEntityHelper.isEmpty(musicStyle.getUniqueId())){
				musicStyle.setUniqueId(EntityHelper.createUniqueId());
			}
			
			Object[] parentParams=QueryHelper.getFieldsVal(musicStyle.getParent(), IBaseEntityDao.BASEPROPERTYNAMES);
			Object[] musicStyleParams=QueryHelper.getFieldsVal(musicStyle, IMusicStyleDao.BASEPROPERTYNAMES);
			propertyValues=EntityHelper.groupArrays(parentParams, musicStyleParams);

			propertyNames=EntityHelper.groupArrays(IBaseEntityDao.BASEPROPERTYNAMES, IMusicStyleDao.BASEPROPERTYNAMES);
			sqlStr=QueryHelper.getInsertSQLByProperty(MusicStyleDaoImpl.TABLEMANE, propertyNames);
			
		}else{
			
			if(GEntityHelper.isEmpty(propertyNames) || 
					EntityHelper.containBaseEntityPropertyName(propertyNames) == true){
				propertyNames=IMusicStyleDao.BASEPROPERTYNAMES;
			}
			
			propertyValues=QueryHelper.getFieldsVal(musicStyle, propertyNames);
			sqlStr=QueryHelper.getUpdateSQL(MusicStyleDaoImpl.TABLEMANE, musicStyle,"id="+musicStyle.getId(), propertyNames);
			
		}
		
		try {
			
			return QueryHelper.update(sqlStr, propertyValues);
			
		} catch (DBException e) {
			log.error("[function: createOrUpdateMusicStyle]", e);
			throw new DaoException("create or update musicStyle faliure");
		}

	}

	public int[] createSingerMusicStyleRelevanceByMusicStyle(MusicStyle musicStyle)
			throws DaoException {
		if(!GEntityHelper.checkIDAndUniqueIdWhetherIegal(musicStyle) || 
				GEntityHelper.isEmpty(musicStyle.getSingers())){
			return null;
		}
		
		Set<Singer> singers=(Set<Singer>) GEntityHelper.findAllIdAndUniqueIdIsNotNull(musicStyle.getSingers());
		
		if(GEntityHelper.isEmpty(singers)){
			return null;
		}
		
		Object[][] params = EntityHelper.initRelevanceParamsById(musicStyle, singers);
		
		String sqlStr=QueryHelper.getInsertSQLByProperty(RelationTable.SINGER_MUSIC_STYLE_TABLE, 
				"music_style_id", "singer_id");
		
		
		try {
			return QueryHelper.batch(sqlStr, params);
		} catch (DBException e) {
			log.error("[function: createSingerMusicStyleByMusicStyle]", e);
			throw new DaoException("create singer musicStyle relevance by musicStyle failure");
		}
		
	}

	public int[] createSongMusicStyleRelevanceByMusicStyle(MusicStyle musicStyle)
			throws DaoException {
		if(!GEntityHelper.checkIDAndUniqueIdWhetherIegal(musicStyle) || 
				GEntityHelper.isEmpty(musicStyle.getSongs())){
			return null;
		}
		
		Set<Song> songs=(Set<Song>) GEntityHelper.findAllIdAndUniqueIdIsNotNull(
				musicStyle.getSongs());
		
		if(GEntityHelper.isEmpty(songs)){
			return null;
		}
		
		Object[][] params = EntityHelper.initRelevanceParamsById(musicStyle, songs);
		
		String sqlStr=QueryHelper.getInsertSQLByProperty(
				RelationTable.SONG_MUSIC_STYLE_TABLE, "music_style_id", "song_id");
		
		try {
			return QueryHelper.batch(sqlStr, params);
		} catch (DBException e) {
			log.error("[function: createSongMusicStyleRelevanceByMusicStyle]", e);
			throw new DaoException("create song musicStyle relevance by musicStyle failure");
		}

	}

	public int deleteMusicStyleByMusicStyleId(long id) throws DaoException {
		
		if(id <= 0){
			return -1;
		}
		
		String sqlStr=QueryHelper.getDeleteSQL(MusicStyleDaoImpl.TABLEMANE, "id=?");
		
		try {
			return QueryHelper.update(sqlStr, id);
		} catch (DBException e) {
			log.error("[function: deleteMusicStyleByMusicStyleId]", e);
			throw new DaoException(" delete musicStyle by id failure");
		}
	}

	public List<MusicStyle> getAllMusicStyles() throws DaoException {
		
		String str=QueryHelper.getSelectSQL(MusicStyleDaoImpl.TABLEMANE, "");
		String sqlStr=MessageFormat.format("{0} ORDER BY {1}.styleName=?, {1}.styleName ASC", 
				str, MusicStyleDaoImpl.TABLEMANE);
		try {
			return QueryHelper.query(MusicStyle.class, sqlStr, "Other");
		} catch (DBException e) {
			log.error("[function: getAllMusicStyles]", e);
			throw new DaoException("get all musicStyles failure");
		}
		
	}

	public long getAllMusicStylesCount() throws DaoException {
		
		Object[] objects=null;
		try {
			return QueryHelper.stat("SELECT COUNT(id) FROM "+MusicStyleDaoImpl.TABLEMANE, objects);
		} catch (DBException e) {
			log.error("[function: getAllMusicStylesCount]", e);
			throw new DaoException("get all musicStyles count failure");
		}
	}

	public List<MusicStyle> getMusicStrylesBySingerId(long id)
			throws DaoException {
		
		if(id <= 1L){
			return null;
		}
		
		String sqlStr=MessageFormat.format("SELECT DISTINCT {0}.* FROM {0}, {1} WHERE " +
				"{0}.id={1}.music_style_id AND {1}.singer_id=?", MusicStyleDaoImpl.TABLEMANE, 
					RelationTable.SINGER_MUSIC_STYLE_TABLE);
		
		try {
			return QueryHelper.query(MusicStyle.class, sqlStr, id);
		} catch (DBException e) {
			log.error("[function: getMusicStrylesBySingerId]", e);
			throw new DaoException("get music styles by singer id failure");
		}
	}

	public MusicStyle getMusicStyleByMusicStyleId(long id) throws DaoException {
		
		if( id <= 0){
			return null;
		}
		
		try {
			String sqlStr=QueryHelper.getSelectSQL(MusicStyleDaoImpl.TABLEMANE, "id=?");
			return QueryHelper.read(MusicStyle.class, sqlStr, id);
		} catch (DBException e) {
			log.error("[function: getMusicStyleByMusicStyleId]", e);
			throw new DaoException("get musicStyle by id failure");
		}
	}

	public MusicStyle getMusicStyleByMusicStyleUniqueId(String uniqueId)
			throws DaoException {
		if(GEntityHelper.isEmpty(uniqueId)){
			return null;
		}
		
		String sqlStr=QueryHelper.getSelectSQL(MusicStyleDaoImpl.TABLEMANE, "uniqueId=?");
		
		try {
			return QueryHelper.read(MusicStyle.class, sqlStr, uniqueId);
		} catch (DBException e) {
			log.error("[function: getMusicStyleByMusicStyleUniqueId]", e);
			throw new DaoException("get music style by music style unqiueId failure");
		}
	}

	public List<MusicStyle> getMusicStylesBySongId(long id) throws DaoException {
		
		if(id <= 0){
			return null;
		}
		
		String sqlStr=MessageFormat.format("SELECT DISTINCT {0}.* FROM {0}, {1} WHERE " +
				"{0}.id={1}.music_style_id AND {1}.song_id=?", MusicStyleDaoImpl.TABLEMANE, 
					RelationTable.SONG_MUSIC_STYLE_TABLE);
		
		try {
			return QueryHelper.query(MusicStyle.class, sqlStr, id);
		} catch (DBException e) {
			log.error("[function: getMusicStylesBySongId]", e);
			throw new DaoException("get music styles by song id failure");
		}
	
	}

	public int[] removeSingerMusicStyleRelevanceByMusicStyle(MusicStyle musicStyle)
			throws DaoException {
		if(!GEntityHelper.checkIDAndUniqueIdWhetherIegal(musicStyle) || 
				GEntityHelper.isEmpty(musicStyle.getSingers())){
			return null;
		}
		
		Set<Singer> singers=(Set<Singer>) GEntityHelper.findAllIdAndUniqueIdIsNotNull(musicStyle.getSingers());
		
		if(GEntityHelper.isEmpty(singers)){
			return null;
		}
		
		Object[][] params = EntityHelper.initRelevanceParamsById(musicStyle, singers);
		
		String sqlStr=QueryHelper.getDeleteSQL(RelationTable.SINGER_MUSIC_STYLE_TABLE, 
				"music_style_id=? AND singer_id=?");
		
		
		try {
			return QueryHelper.batch(sqlStr, params);
		} catch (DBException e) {
			log.error("[function: removeSingerMusicStyleByMusicStyle]", e);
			throw new DaoException("remove singer musicStyle relevance by musicStyle failure");
		}
	}

	public int[] removeSongMusicStyleRelevanceByMusicStyle(MusicStyle musicStyle)
			throws DaoException {
		if(!GEntityHelper.checkIDAndUniqueIdWhetherIegal(musicStyle) || 
				GEntityHelper.isEmpty(musicStyle.getSongs())){
			return null;
		}
		
		Set<Song> songs=(Set<Song>) GEntityHelper.findAllIdAndUniqueIdIsNotNull(
				musicStyle.getSongs());
		
		if(GEntityHelper.isEmpty(songs)){
			return null;
		}
		
		Object[][] params = EntityHelper.initRelevanceParamsById(musicStyle, songs);
		
		String sqlStr=QueryHelper.getDeleteSQL(
				RelationTable.SONG_MUSIC_STYLE_TABLE, "music_style_id=? AND song_id=? ");
		
		try {
			return QueryHelper.batch(sqlStr, params);
		} catch (DBException e) {
			log.error("[function: createSongMusicStyleRelevanceByMusicStyle]", e);
			throw new DaoException("create song musicStyle relevance by musicStyle failure");
		}
	}

	public List<MusicStyle> getMusicStylesByAlbumId(long id)
			throws DaoException {
		if(id <= 0){
			return null;
		}
		
		String sqlStr=MessageFormat.format("SELECT  DISTINCT {0}.* FROM {0}, {1} " +
				"WHERE {0}.id={1}.music_style_id AND {1}.album_id=?", 
					MusicStyleDaoImpl.TABLEMANE, RelationTable.ALBUM_MUSIC_STYLE_TABLE);
		
		try {
			return QueryHelper.query(MusicStyle.class, sqlStr, id);
		} catch (DBException e) {
			log.error("[function: getMusicStylesByAlbumId]", e);
			throw new DaoException("get music styles by album id failure");
		}

	}
	
}
